package com.bestvike.stone.core.reflect;

import org.springframework.util.Assert;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Objects;

/**
 * Created by 许崇雷 on 2017-10-10.
 */
@SuppressWarnings("unused")
public abstract class GenericTypeReference<T> {
    private final Type type;

    protected GenericTypeReference() {
        ParameterizedType superClass = (ParameterizedType) this.getClass().getGenericSuperclass();
        this.type = superClass.getActualTypeArguments()[0];
    }

    private GenericTypeReference(Type type) {
        Assert.notNull(type, "type can not be null");
        this.type = type;
    }

    public static <T> GenericTypeReference<T> forType(Type type) {
        return new GenericTypeReference<T>(type) {
        };
    }

    public Type getType() {
        return this.type;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!(obj instanceof GenericTypeReference))
            return false;
        GenericTypeReference<?> that = (GenericTypeReference<?>) obj;
        return Objects.equals(this.type, that.type);
    }

    @Override
    public int hashCode() {
        return this.type.hashCode();
    }

    @Override
    public String toString() {
        return "GenericTypeReference<" + this.type + ">";
    }
}
